﻿
<#
.SYNOPSIS
Throws an assertion failure.
#>
function Assert-Fail {
    [Cmdletbinding()]
    Param
    (
        [string] $Message = "Unknown failure.",
        [string] $Failure = "Assertion Failure"
    )
    
    [string] $msg

    if($Message) {
        $msg += "Message : $Message"
        if ($Failure) {
            $msg += "`n"
            }
    }

    if ($Failure) {
        $msg += "$Failure"
    }

    Write-Trace $msg

    throw $msg
}

<#
.SYNOPSIS
Asserts that an actual value is equal to $true.
#>
function Assert-IsTrue {
    [Cmdletbinding()]
    Param
    (
        [Parameter(Mandatory=$true)]
        [bool] $Actual = $(throw "parameter 'Actual' is required."),
        [string] $Message
    )

    Assert-AreEqual `
        -Expected $true `
        -Actual $Actual `
        -Message $Message
}

<#
.SYNOPSIS
Asserts that an actual value is equal to $false.
#>
function Assert-IsFalse {
    [Cmdletbinding()]
    Param
    (
        [Parameter(Mandatory=$true)]
        [bool] $Actual = $(throw "parameter 'Actual' is required."),
        [string] $Message
    )

    Assert-AreEqual `
        -Expected $false `
        -Actual $Actual `
        -Message $Message
}

<#
.SYNOPSIS
Asserts that an actual value is equal to $null.
#>
function Assert-IsNull {
    [Cmdletbinding()]
    Param
    (
        $Actual = $(throw "parameter 'Actual' is required."),
        [string] $Message
    )

    Assert-AreEqual `
        -Expected $null `
        -Actual $Actual `
        -Message $Message
}

<#
.SYNOPSIS
Asserts that an actual value is not equal to $null.
#>
function Assert-IsNotNull {
    [Cmdletbinding()]
    Param
    (
        $Actual = $(throw "parameter 'Actual' is required."),
        [string] $Message
    )

    Assert-AreNotEqual `
        -NotExpected $null `
        -Actual $Actual `
        -Message $Message
}

<#
.SYNOPSIS
Asserts that a given collection is $null or empty
#>
function Assert-IsEmpty {
    [Cmdletbinding()]
    Param
    (
        [Object[]] $Actual = $(throw "parameter 'Actual' is required."),
        [string] $Message
    )

    if ($Actual -and $Actual.Count -and $Actual.Count -gt 0) {
        Assert-Fail `
            -Failure "Collection is not empty." `
            -Message $Message
    }
}

<#
.SYNOPSIS
Asserts that a given collection is not $null and not empty
#>
function Assert-IsNotEmpty {
    [Cmdletbinding()]
    Param
    (
        [object[]] $Actual = $(throw "parameter 'Actual' is required."),
        [string] $Message
    )

    Assert-IsNotNull `
        -Actual $Actual `
        -Message $Message

    if ($Actual.Count -eq 0) {
        Assert-Fail `
            -Failure "A non-empty collection was expected, but actual is empty." `
            -Message $Message
    }
}

<#
.SYNOPSIS
Asserts that an actual value is equal to an expected value.
#>
function Assert-AreEqual {
    [Cmdletbinding()]
    Param
    (
        $Expected = $(throw "parameter 'Expected' is required."),
        $Actual = $(throw "parameter 'Actual' is required."),
        [string] $Message
    )

    Write-Trace "Asserting that '$Actual' is equal to '$Expected'."

    if ($Actual -ne $Expected) {
        Assert-Fail `
            -Failure "A value equal to '$Expected' was expected, but '$Actual' is found." `
            -Message $Message
    }
}

<#
.SYNOPSIS
Asserts that an actual value is not equal to an not expected value.
#>
function Assert-AreNotEqual {
    [Cmdletbinding()]
    Param
    (
        $NotExpected = $(throw "parameter 'NotExpected' is required."),
        $Actual = $(throw "parameter 'Actual' is required."),
        [string] $Message
    )
    if ($Actual -eq $NotExpected) {
        Assert-Fail `
            -Failure "A value not equal to '$NotExpected' was expected, but '$Actual' is found." `
            -Message $Message
    }
}

<#
.SYNOPSIS
Asserts that an exception occurs in a given scriptblock.
#>
function Assert-Exception {
    [Cmdletbinding()]
    Param
    (
        [Parameter(Mandatory=$true)]
        [ScriptBlock] $Script = $null,
        [string] $Message
    )

    [bool]$exception = $false

    try {
        &$Script
    }
    catch {
        $exception = $true
    }

    if (!$exception) {
        Assert-Fail `
            -Failure "An expected exception was not thrown." `
            -Message $Message
        }
}
